﻿/*
l * histool.cpp
 *
 *  Created on: 2017年7月13日
 *      Author: work
 */

#include <boost/program_options.hpp>

#include <dm/scada/scadahis.hpp>
#include <dm/scada/statusmgr.hpp>
#include <dm/scada/discretemgr.hpp>
#include <dm/scada/measuremgr.hpp>
#include <dm/scada/cumulantmgr.hpp>
#include <dm/scada/actionmgr.hpp>
#include <dm/datetime.hpp>
#include <iostream>
#include <vector>

using namespace std;
using namespace boost::program_options;

void cmd_info( const variables_map& vm );
void cmd_first( const variables_map& vm );
void cmd_last( const variables_map& vm );
void cmd_next( const variables_map& vm );
void cmd_previous( const variables_map& vm );
void cmd_at( const variables_map& vm );
void cmd_clear( const variables_map& vm );
void cmd_data( const variables_map& vm );
void cmd_curve( const variables_map& vm );
void cmd_test( const variables_map& vm );
void cmd_init( const variables_map& vm );

int main( int argc,char* argv[] ){
	options_description desc("【DM2016帮助文档】\n 历史数据工具。\n\t基于DM2016系统构建\n支持以下选项");

	options_description opts_generic("一般选项");
	opts_generic.add_options()
			("help,h","显示本帮助信息")
			("version,v","显示版本及编译信息")
			;
	desc.add(opts_generic);

	options_description opts_cmd("命令选项");
	opts_cmd.add_options()
			("info","查询记录信息")
			("first","查询第一条记录")
			("last","查询最后一条记录")
			("next","查询后一条记录")
			("previous","查询前一条记录")
			("at","查询指定时刻的记录信息")
			("data","查询记录数据信息")
			("curve","查询指定记录并以曲线显示")
			("test","增加测试数据")
			("clear",value<string>(),"清除数据。\nall：全部记录\nbefore:指定时刻之前的记录\nafter:指定时刻之后的记录\andbefore:指定时刻及之前的记录\nandafter:指定时刻及之后的记录")
			("init","重新初始化历史数据库")
			;
	desc.add(opts_cmd);

	options_description opts_paras("辅助参数");
	opts_paras.add_options()
			("all,a","全部数据类型")
			("status,s","指定数据类型为状态量")
			("discrete,d","指定数据类型为离散量")
			("measure,m","指定数据类型为测量量")
			("cumulant,c","指定数据类型为累计量")
			("action,o","指定数据类型为动作")
			("name,n",value<string>(),"指定数据类型的名字")
			("id",value<int>(),"指定点ID")
			("value",value<string>(),"指定数据值。使用十进制表示。如：10, 4.91")
			("timestamp,t",value<string>(),"指定数据时标。\n不指定时，一般用当前时标。如：2017-07-13 08:45:59.104")
			("before",value<string>(),"指定时标结束")
			("after",value<string>(),"指定时标开始")
			("secs",value<int>(),"曲线时长。单位:秒")
			("x-len",value<int>(),"坐标x轴长度，默认200个点。")
			("y-len",value<int>(),"坐标y轴长度，默认50个点。")
			;
	desc.add(opts_paras);

	variables_map vm;
	try{
		store(parse_command_line(argc,argv,desc),vm);
		notify(vm);
	}catch( std::exception& ex ){
		cout << ex.what()<<endl;
		return 1;
	}

	if( vm.count("version") ){
		cout <<"V1.0 构建于 "<<__DATE__<<endl;
		return 1;
	}

	if( vm.count("help") ){
		cout <<desc<<endl;
		return 1;
	}

	if( vm.count("info") ){
		cmd_info(vm);
	}else if( vm.count("first") ){
		cmd_first(vm);
	}else if( vm.count("last") ){
		cmd_last(vm);
	}else if( vm.count("next") ){
		cmd_next(vm);
	}else if( vm.count("previous") ){
		cmd_previous(vm);
	}else if( vm.count("at") ){
		cmd_at(vm);
	}else if( vm.count("clear") ){
		cmd_clear(vm);
	}else if( vm.count("data") ){
		cmd_data(vm);
	}else if( vm.count("curve") ){
		cmd_curve(vm);
	}else if( vm.count("test") ){
		cmd_test(vm);
	}else if( vm.count("init") ){
		cmd_init(vm);
	}

	return 0;
}

template<typename TInfo,typename TMgr>
const TInfo* getInfo( const variables_map& vm,const char* typeName ){
	int idx;
	if( vm.count("id") ){
		idx = TMgr::ins().indexById( vm["id"].as<int>() );
		if( idx<0 ){
			cout <<"不能找到"<<typeName<<" id="<<vm["id"].as<int>()<<endl;
			return NULL;
		}
	}else if( vm.count("name")){
		idx = TMgr::ins().indexByName(vm["name"].as<string>().c_str());
		if( idx<0 ){
			cout <<"不能找到"<<typeName<<" name="<<vm["name"].as<string>()<<endl;
			return NULL;
		}
	}else{
		cout <<"请用--id或者--name指定"<<typeName<<"信息"<<endl;
		return NULL;
	}

	return TMgr::ins().info(idx);
}

template<typename TMgr,typename TInfo,typename TRcd>
void showInfo( const variables_map& vm,const char* typeName,
		int (dm::scada::CScadaHis::*fGetCount)(const char* ),
		bool (dm::scada::CScadaHis::*fGetFirst)(TRcd& rcd),
		bool (dm::scada::CScadaHis::*fGetLast)(TRcd& rcd),
		bool (dm::scada::CScadaHis::*fGetBegin)( dm::CTimeStamp&,const char* ),
		bool (dm::scada::CScadaHis::*fGetEnd)( dm::CTimeStamp&,const char* )
		){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
	dm::CTimeStamp ts;
	dm::CDateTime dt;

	if( vm.count("id") || vm.count("name") ){
		const TInfo* info = getInfo<TInfo,TMgr>(vm,typeName);

		cout <<info->name.c_str()
				<<" 记录数:"<<(his.*fGetCount)(info->name.c_str());

		TRcd rcd;
		rcd.name = info->name;
		(his.*fGetFirst)(rcd);

		dt = rcd.ts;

		cout <<" 起始时刻:"<<dt.toString();

		(his.*fGetLast)(rcd);
		dt = rcd.ts;
		cout <<" 最后时刻："<<dt.toString()
				<<endl;
	}else{
		cout <<" 记录数:"<<(his.*fGetCount)(NULL);

		(his.*fGetBegin)(ts,NULL);

		dt = ts;

		cout <<" 起始时刻:"<<dt.toString();

		(his.*fGetEnd)(ts,NULL);
		dt = ts;
		cout <<" 最后时刻："<<dt.toString()
				<<endl;
	}
}

/**
 * 显示信息
 * @param vm在此作用域中尚未声明
 */
void cmd_info( const variables_map& vm ){
	if( vm.count("status") ){
		cout <<"状态量 ";
		showInfo<dm::scada::CStatusMgr,dm::scada::SStatusInfo,dm::scada::SHisRcdStatus>(vm,"状态量",
				&dm::scada::CScadaHis::getStatusCount,
				&dm::scada::CScadaHis::getFirstStatus,
				&dm::scada::CScadaHis::getLastStatus,
				&dm::scada::CScadaHis::getBeginOfStatus,
				&dm::scada::CScadaHis::getEndOfStatus
				);
	}else if( vm.count("discrete") ){
		cout <<"离散量 ";
		showInfo<dm::scada::CDiscreteMgr,dm::scada::SDiscreteInfo,dm::scada::SHisRcdDiscrete>(vm,"离散量",
				&dm::scada::CScadaHis::getDiscreteCount,
				&dm::scada::CScadaHis::getFirstDiscrete,
				&dm::scada::CScadaHis::getLastDiscrete,
				&dm::scada::CScadaHis::getBeginOfDiscrete,
				&dm::scada::CScadaHis::getEndOfDiscrete
				);
	}else if( vm.count("measure")){
		cout <<"测量量 ";
		showInfo<dm::scada::CMeasureMgr,dm::scada::SMeasureInfo,dm::scada::SHisRcdMeasure>(vm,"测量量",
				&dm::scada::CScadaHis::getMeasureCount,
				&dm::scada::CScadaHis::getFirstMeasure,
				&dm::scada::CScadaHis::getLastMeasure,
				&dm::scada::CScadaHis::getBeginOfMeasure,
				&dm::scada::CScadaHis::getEndOfMeasure
				);
	}else if( vm.count("cumulant") ){
		cout <<"累计量 ";
		showInfo<dm::scada::CCumulantMgr,dm::scada::SCumulantInfo,dm::scada::SHisRcdCumulant>(vm,"累计量",
				&dm::scada::CScadaHis::getCumulantCount,
				&dm::scada::CScadaHis::getFirstCumulant,
				&dm::scada::CScadaHis::getLastCumulant,
				&dm::scada::CScadaHis::getBeginOfCumulant,
				&dm::scada::CScadaHis::getEndOfCumulant
				);
	}else if( vm.count("action") ){
		cout <<"动作 ";
		showInfo<dm::scada::CActionMgr,dm::scada::SActionInfo,dm::scada::SHisRcdAction>(vm,"动作",
				&dm::scada::CScadaHis::getActionCount,
				&dm::scada::CScadaHis::getFirstAction,
				&dm::scada::CScadaHis::getLastAction,
				&dm::scada::CScadaHis::getBeginOfAction,
				&dm::scada::CScadaHis::getEndOfAction
				);
	}else{
		dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
		dm::CTimeStamp ts;
		dm::CDateTime dt;

		cout <<"状态量 ";
		if( his.getBeginOfStatus(ts) ){
			dt = ts;
			cout<<" 起始时刻:"<<dt.toString();

			his.getEndOfStatus(ts);
			dt = ts;
			cout <<" 结束时刻:"<<dt.toString()<<endl;
		}else{
			cout <<"没有记录"<<endl;
		}

		cout <<"离散量 ";
		if( his.getBeginOfDiscrete(ts) ){
			dt = ts;
			cout<<" 起始时刻:"<<dt.toString();

			his.getEndOfDiscrete(ts);
			dt = ts;
			cout <<" 结束时刻:"<<dt.toString()<<endl;
		}else{
			cout <<"没有记录"<<endl;
		}

		cout <<"测量量 ";
		if( his.getBeginOfMeasure(ts) ){
			dt = ts;
			cout<<" 起始时刻:"<<dt.toString();

			his.getEndOfMeasure(ts);
			dt = ts;
			cout <<" 结束时刻:"<<dt.toString()<<endl;
		}else{
			cout <<"没有记录"<<endl;
		}

		cout <<"累计量 ";
		if( his.getBeginOfCumulant(ts) ){
			dt = ts;
			cout<<" 起始时刻:"<<dt.toString();

			his.getEndOfCumulant(ts);
			dt = ts;
			cout <<" 结束时刻:"<<dt.toString()<<endl;
		}else{
			cout <<"没有记录"<<endl;
		}
	}
}

template<typename TMgr,typename TInfo,typename TRcd>
void showFirstOrLast( const variables_map& vm,const char* typeName,bool (dm::scada::CScadaHis::*fGetFirst)(TRcd&) ){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
	dm::CTimeStamp ts;
	dm::CDateTime dt;

	cout <<typeName;
	const TInfo* info = getInfo<TInfo,TMgr>(vm,typeName);
	if( info ){
		cout <<info->name.c_str();

		TRcd rcd;
		rcd.name = info->name;
		if( (his.*fGetFirst)(rcd) ){
			dt = rcd.ts;
			cout <<" 起始记录 时刻:"<< dt.toString()<<" 值:"<<rcd.v;
			dt = rcd.op;
			cout <<" 保存时刻:"<<dt.toString();
		}else{
			cout <<" 没有记录";
		}
		cout <<endl;
	}
}

void cmd_first( const variables_map& vm ){
	if( vm.count("status") ){
		showFirstOrLast<dm::scada::CStatusMgr,dm::scada::SStatusInfo,dm::scada::SHisRcdStatus>(vm,"状态量",&dm::scada::CScadaHis::getFirstStatus);
	}else if( vm.count("discrete") ){
		showFirstOrLast<dm::scada::CDiscreteMgr,dm::scada::SDiscreteInfo,dm::scada::SHisRcdDiscrete>(vm,"离散量",&dm::scada::CScadaHis::getFirstDiscrete);
	}else if( vm.count("measure")){
		showFirstOrLast<dm::scada::CMeasureMgr,dm::scada::SMeasureInfo,dm::scada::SHisRcdMeasure>(vm,"测量量",&dm::scada::CScadaHis::getFirstMeasure);
	}else if( vm.count("cumulant") ){
		showFirstOrLast<dm::scada::CCumulantMgr,dm::scada::SCumulantInfo,dm::scada::SHisRcdCumulant>(vm,"累计量",&dm::scada::CScadaHis::getFirstCumulant);
	}else if( vm.count("action") ){
		showFirstOrLast<dm::scada::CActionMgr,dm::scada::SActionInfo,dm::scada::SHisRcdAction>(vm,"动作",&dm::scada::CScadaHis::getFirstAction);
	}else{
		cout <<"请指定要查询的点信息"<<endl;
	}
}

void cmd_last( const variables_map& vm ){
	if( vm.count("status") ){
		showFirstOrLast<dm::scada::CStatusMgr,dm::scada::SStatusInfo,dm::scada::SHisRcdStatus>(vm,"状态量",&dm::scada::CScadaHis::getLastStatus);
	}else if( vm.count("discrete") ){
		showFirstOrLast<dm::scada::CDiscreteMgr,dm::scada::SDiscreteInfo,dm::scada::SHisRcdDiscrete>(vm,"离散量",&dm::scada::CScadaHis::getLastDiscrete);
	}else if( vm.count("measure")){
		showFirstOrLast<dm::scada::CMeasureMgr,dm::scada::SMeasureInfo,dm::scada::SHisRcdMeasure>(vm,"测量量",&dm::scada::CScadaHis::getLastMeasure);
	}else if( vm.count("cumulant") ){
		showFirstOrLast<dm::scada::CCumulantMgr,dm::scada::SCumulantInfo,dm::scada::SHisRcdCumulant>(vm,"累计量",&dm::scada::CScadaHis::getLastCumulant);
	}else if( vm.count("action") ){
		showFirstOrLast<dm::scada::CActionMgr,dm::scada::SActionInfo,dm::scada::SHisRcdAction>(vm,"动作",&dm::scada::CScadaHis::getLastAction);
	}else{
		cout <<"请指定要查询的点信息"<<endl;
	}
}

template<typename TMgr,typename TInfo,typename TRcd>
void showNextOrPrevious( const variables_map& vm,const char* typeName,bool (dm::scada::CScadaHis::*fGet)(TRcd&) ){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
	dm::CTimeStamp ts;
	dm::CDateTime dt;

	if( !vm.count("timestamp") ){
		cout <<"请使用--timestamp指定时刻"<<endl;
		return;
	}

	if( !dt.fromString(vm["timestamp"].as<string>().c_str()) ){
		cout <<"--timestamp时标格式不正确"<<vm["timestamp"].as<string>()<<endl;
		return;
	}

	cout <<typeName;
	const TInfo* info = getInfo<TInfo,TMgr>(vm,typeName);
	if( info ){
		cout <<info->name.c_str()
				<<" 时刻:"<<dt.toString();

		TRcd rcd;
		rcd.name = info->name;
		dt.toTimeStamp(rcd.ts);

		if( (his.*fGet)(rcd) ){
			dt = rcd.ts;
			cout <<" 记录时刻:"<< dt.toString()<<" 值:"<<rcd.v;
			dt = rcd.op;
			cout <<" 保存时刻:"<<dt.toString();
		}else{
			cout <<" 没有记录";
		}
		cout <<endl;
	}
}

void cmd_next( const variables_map& vm ){
	if( vm.count("status") ){
		showNextOrPrevious<dm::scada::CStatusMgr,dm::scada::SStatusInfo,dm::scada::SHisRcdStatus>(vm,"下一条状态量",&dm::scada::CScadaHis::getNextStatus);
	}else if( vm.count("discrete") ){
		showNextOrPrevious<dm::scada::CDiscreteMgr,dm::scada::SDiscreteInfo,dm::scada::SHisRcdDiscrete>(vm,"下一条离散量",&dm::scada::CScadaHis::getNextDiscrete);
	}else if( vm.count("measure")){
		showNextOrPrevious<dm::scada::CMeasureMgr,dm::scada::SMeasureInfo,dm::scada::SHisRcdMeasure>(vm,"下一条测量量",&dm::scada::CScadaHis::getNextMeasure);
	}else if( vm.count("cumulant") ){
		showNextOrPrevious<dm::scada::CCumulantMgr,dm::scada::SCumulantInfo,dm::scada::SHisRcdCumulant>(vm,"下一条累计量",&dm::scada::CScadaHis::getNextCumulant);
	}else if( vm.count("action") ){
		showNextOrPrevious<dm::scada::CActionMgr,dm::scada::SActionInfo,dm::scada::SHisRcdAction>(vm,"下一条动作",&dm::scada::CScadaHis::getNextAction);
	}else{
		cout <<"请指定要查询的点信息"<<endl;
	}
}

void cmd_previous( const variables_map& vm ){
	if( vm.count("status") ){
		showNextOrPrevious<dm::scada::CStatusMgr,dm::scada::SStatusInfo,dm::scada::SHisRcdStatus>(vm,"上一条状态量",&dm::scada::CScadaHis::getPreviousStatus);
	}else if( vm.count("discrete") ){
		showNextOrPrevious<dm::scada::CDiscreteMgr,dm::scada::SDiscreteInfo,dm::scada::SHisRcdDiscrete>(vm,"上一条离散量",&dm::scada::CScadaHis::getPreviousDiscrete);
	}else if( vm.count("measure")){
		showNextOrPrevious<dm::scada::CMeasureMgr,dm::scada::SMeasureInfo,dm::scada::SHisRcdMeasure>(vm,"上一条测量量",&dm::scada::CScadaHis::getPreviousMeasure);
	}else if( vm.count("cumulant") ){
		showNextOrPrevious<dm::scada::CCumulantMgr,dm::scada::SCumulantInfo,dm::scada::SHisRcdCumulant>(vm,"上一条累计量",&dm::scada::CScadaHis::getPreviousCumulant);
	}else if( vm.count("action") ){
		showNextOrPrevious<dm::scada::CActionMgr,dm::scada::SActionInfo,dm::scada::SHisRcdAction>(vm,"上一条动作",&dm::scada::CScadaHis::getPreviousAction);
	}else{
		cout <<"请指定要查询的点信息"<<endl;
	}
}

template<typename TMgr,typename TInfo,typename TRcd>
void showByTime( const variables_map& vm,const char* typeName,bool (dm::scada::CScadaHis::*fGet)(TRcd&) ){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
	dm::CTimeStamp ts;
	dm::CDateTime dt;

	if( !vm.count("timestamp") ){
		cout <<"请使用--timestamp指定时刻"<<endl;
		return;
	}

	if( !dt.fromString(vm["timestamp"].as<string>().c_str()) ){
		cout <<"--timestamp时标格式不正确"<<vm["timestamp"].as<string>()<<endl;
		return;
	}

	cout <<typeName;
	const TInfo* info = getInfo<TInfo,TMgr>(vm,typeName);
	if( info ){
		cout <<info->name.c_str();

		TRcd rcd;
		rcd.name = info->name;
		dt.toTimeStamp(rcd.ts);

		if( (his.*fGet)(rcd) ){
			dt = rcd.ts;
			cout <<" 记录时刻:"<< dt.toString()<<" 值:"<<rcd.v;
			dt = rcd.op;
			cout <<" 保存时刻:"<<dt.toString();
		}else{
			cout <<" 没有记录";
		}
		cout <<endl;
	}
}

void cmd_at( const variables_map& vm ){
	if( vm.count("status") ){
		showByTime<dm::scada::CStatusMgr,dm::scada::SStatusInfo,dm::scada::SHisRcdStatus>(vm,"特定时刻状态量",&dm::scada::CScadaHis::statusAt);
	}else if( vm.count("discrete") ){
		showByTime<dm::scada::CDiscreteMgr,dm::scada::SDiscreteInfo,dm::scada::SHisRcdDiscrete>(vm,"特定时刻离散量",&dm::scada::CScadaHis::discreteAt);
	}else if( vm.count("measure")){
		showByTime<dm::scada::CMeasureMgr,dm::scada::SMeasureInfo,dm::scada::SHisRcdMeasure>(vm,"特定时刻测量量",&dm::scada::CScadaHis::measureAt);
	}else if( vm.count("cumulant") ){
		showByTime<dm::scada::CCumulantMgr,dm::scada::SCumulantInfo,dm::scada::SHisRcdCumulant>(vm,"特定时刻累计量",&dm::scada::CScadaHis::cumulantAt);
	}else if( vm.count("action") ){
		showByTime<dm::scada::CActionMgr,dm::scada::SActionInfo,dm::scada::SHisRcdAction>(vm,"特定时刻动作",&dm::scada::CScadaHis::actionAt);
	}else{
		cout <<"请指定要查询的点信息"<<endl;
	}
}

/**
 * 清除所有时间段的数据
 * @param vm
 * @param typeName
 * @param fClearAll
 * @param fClear
 */
template<typename TInfo,typename TMgr>
void clearAll( const variables_map& vm,const char* typeName,void (dm::scada::CScadaHis::*fClearAll)(const char*),void (dm::scada::CScadaHis::*fClear)(const char*) ){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
	if( vm.count("id") || vm.count("name") ){
		const TInfo* info = getInfo<TInfo,TMgr>(vm,typeName);
		if( info ){
			cout <<"将清除"<<typeName<<info->name.c_str() <<"的历史数据。确认?(Y/N):";
			cout.flush();
			if( cin.get()=='Y' ){
				cout <<"清除"<<typeName<<"..."<<endl;
				(his.*fClear)(info->name.c_str());

				cout <<"完成"<<endl;
			}
		}
	}else{
		cout <<"将清除所有"<<typeName<<"历史数据。确认?(Y/N):";
		cout.flush();
		if( cin.get()=='Y' ){
			cout <<"清除"<<typeName<<"..."<<endl;
			(his.*fClearAll)(NULL);

			cout <<"完成"<<endl;
		}
	}
}

template<typename TInfo,typename TMgr>
void clearByTime( const variables_map& vm,const char* typeName,const char* timeInfo,void (dm::scada::CScadaHis::*fClearAll)( const dm::CTimeStamp&,const char* ),void (dm::scada::CScadaHis::*fClear)(const dm::CTimeStamp&,const char* ) ){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
	dm::CTimeStamp ts;
	dm::CDateTime dt;

	if( !vm.count("timestamp") ){
		cout <<"请使用--timestamp指定时刻"<<endl;
		return;
	}

	if( !dt.fromString(vm["timestamp"].as<string>().c_str()) ){
		cout <<"--timestamp时标格式不正确"<<vm["timestamp"].as<string>()<<endl;
		return;
	}

	dt.toTimeStamp(ts);

	if( vm.count("id") || vm.count("name") ){
		const TInfo* info = getInfo<TInfo,TMgr>(vm,typeName);
		if( info ){
			cout <<"将清除"<<typeName<<info->name.c_str() <<timeInfo<<dt.toString()<<"的历史数据。确认?(Y/N):";
			cout.flush();
			if( cin.get()=='Y' ){
				cout <<"清除"<<typeName<<"..."<<endl;
				(his.*fClear)(ts,info->name.c_str());

				cout <<"完成"<<endl;
			}
		}
	}else{
		cout <<"将清除所有"<<typeName<<timeInfo<<dt.toString()<<"历史数据。确认?(Y/N):";
		cout.flush();
		if( cin.get()=='Y' ){
			cout <<"清除"<<typeName<<"..."<<endl;
			(his.*fClearAll)(ts,NULL);

			cout <<"完成"<<endl;
		}
	}
}

void cmd_clear( const variables_map& vm ){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
	dm::CTimeStamp ts;
	dm::CDateTime dt;

	if( vm["clear"].as<string>()=="all" ){
		// 清除所有时段的数据
		if( vm.count("status") ){
			clearAll<dm::scada::SStatusInfo,dm::scada::CStatusMgr>(vm,"状态量",&dm::scada::CScadaHis::clearStatus,&dm::scada::CScadaHis::clearStatus);
		}else if( vm.count("discrete") ){
			clearAll<dm::scada::SDiscreteInfo,dm::scada::CDiscreteMgr>(vm,"离散量",&dm::scada::CScadaHis::clearDiscrete,&dm::scada::CScadaHis::clearDiscrete);
		}else if( vm.count("measure") ){
			clearAll<dm::scada::SMeasureInfo,dm::scada::CMeasureMgr>(vm,"测量量",&dm::scada::CScadaHis::clearMeasure,&dm::scada::CScadaHis::clearMeasure);
		}else if( vm.count("cumulant") ){
			clearAll<dm::scada::SCumulantInfo,dm::scada::CCumulantMgr>(vm,"累计量",&dm::scada::CScadaHis::clearCumulant,&dm::scada::CScadaHis::clearCumulant);
		}else if( vm.count("action") ){
			clearAll<dm::scada::SActionInfo,dm::scada::CActionMgr>(vm,"动作",&dm::scada::CScadaHis::clearAction,&dm::scada::CScadaHis::clearAction);
		}else{
			cout <<"将清除所有历史数据。确认?(Y/N):";
			cout.flush();
			if( cin.get()=='Y' ){
				cout <<"清除状态量..."<<endl;
				his.clearStatus();

				cout <<"清除离散量..."<<endl;
				his.clearDiscrete();

				cout <<"清除测量量..."<<endl;
				his.clearMeasure();

				cout <<"清除累计量..."<<endl;
				his.clearMeasure();

				cout <<"清除动作..."<<endl;
				his.clearAction();

				cout <<"完成"<<endl;
			}
		}
	}else if( vm["clear"].as<string>()=="before" ){
		// 清除之前的数据
		if( vm.count("status") ){
			clearByTime<dm::scada::SStatusInfo,dm::scada::CStatusMgr>(vm,"状态量","之前",&dm::scada::CScadaHis::clearStatusBeforeAndComplement,&dm::scada::CScadaHis::clearStatusBeforeAndComplement);
		}else if( vm.count("discrete") ){
			clearByTime<dm::scada::SDiscreteInfo,dm::scada::CDiscreteMgr>(vm,"离散量","之前",&dm::scada::CScadaHis::clearDiscreteBeforeAndComplement,&dm::scada::CScadaHis::clearDiscreteBeforeAndComplement);
		}else if( vm.count("measure") ){
			clearByTime<dm::scada::SMeasureInfo,dm::scada::CMeasureMgr>(vm,"测量量","之前",&dm::scada::CScadaHis::clearMeasureBeforeAndComplement,&dm::scada::CScadaHis::clearMeasureBeforeAndComplement);
		}else if( vm.count("cumulant") ){
			clearByTime<dm::scada::SCumulantInfo,dm::scada::CCumulantMgr>(vm,"累计量","之前",&dm::scada::CScadaHis::clearCumulantBeforeAndComplement,&dm::scada::CScadaHis::clearCumulantBeforeAndComplement);
		}else if( vm.count("action") ){
			clearByTime<dm::scada::SActionInfo,dm::scada::CActionMgr>(vm,"动作","之前",&dm::scada::CScadaHis::clearActionBeforeAndComplement,&dm::scada::CScadaHis::clearActionBeforeAndComplement);
		}else{
			cout <<"将清除"<<dt.toString()<<"之前所有历史数据。确认?(Y/N):";
			cout.flush();
			if( cin.get()=='Y' ){
				cout <<"清除状态量..."<<endl;
				his.clearStatusBeforeAndComplement(ts);

				cout <<"清除离散量..."<<endl;
				his.clearDiscreteBeforeAndComplement(ts);

				cout <<"清除测量量..."<<endl;
				his.clearMeasureBeforeAndComplement(ts);

				cout <<"清除累计量..."<<endl;
				his.clearCumulantBeforeAndComplement(ts);

				cout <<"清除动作..."<<endl;
				his.clearActionBeforeAndComplement(ts);

				cout <<"完成"<<endl;
			}
		}
	}else if( vm["clear"].as<string>()=="after" ){
		// 清除之后的数据
		if( vm.count("status") ){
			clearByTime<dm::scada::SStatusInfo,dm::scada::CStatusMgr>(vm,"状态量","之后",&dm::scada::CScadaHis::clearStatusAfterAndComplement,&dm::scada::CScadaHis::clearStatusAfterAndComplement);
		}else if( vm.count("discrete") ){
			clearByTime<dm::scada::SDiscreteInfo,dm::scada::CDiscreteMgr>(vm,"离散量","之后",&dm::scada::CScadaHis::clearDiscreteAfterAndComplement,&dm::scada::CScadaHis::clearDiscreteAfterAndComplement);
		}else if( vm.count("measure") ){
			clearByTime<dm::scada::SMeasureInfo,dm::scada::CMeasureMgr>(vm,"测量量","之后",&dm::scada::CScadaHis::clearMeasureAfterAndComplement,&dm::scada::CScadaHis::clearMeasureAfterAndComplement);
		}else if( vm.count("cumulant") ){
			clearByTime<dm::scada::SCumulantInfo,dm::scada::CCumulantMgr>(vm,"累计量","之后",&dm::scada::CScadaHis::clearCumulantAfterAndComplement,&dm::scada::CScadaHis::clearCumulantAfterAndComplement);
		}else if( vm.count("action") ){
			clearByTime<dm::scada::SActionInfo,dm::scada::CActionMgr>(vm,"动作","之后",&dm::scada::CScadaHis::clearActionAfterAndComplement,&dm::scada::CScadaHis::clearActionAfterAndComplement);
		}else{
			cout <<"将清除"<<dt.toString()<<"之后所有历史数据。确认?(Y/N):";
			cout.flush();
			if( cin.get()=='Y' ){
				cout <<"清除状态量..."<<endl;
				his.clearStatusAfterAndComplement(ts);

				cout <<"清除离散量..."<<endl;
				his.clearDiscreteAfterAndComplement(ts);

				cout <<"清除测量量..."<<endl;
				his.clearMeasureAfterAndComplement(ts);

				cout <<"清除累计量..."<<endl;
				his.clearCumulantAfterAndComplement(ts);

				cout <<"清除动作..."<<endl;
				his.clearActionAfterAndComplement(ts);

				cout <<"完成"<<endl;
			}
		}
	}else if( vm["clear"].as<string>()=="andbefore" ){
		// 清除含当时及以前的数据
		if( vm.count("status") ){
			clearByTime<dm::scada::SStatusInfo,dm::scada::CStatusMgr>(vm,"状态量","及之前",&dm::scada::CScadaHis::clearStatusBefore,&dm::scada::CScadaHis::clearStatusBefore);
		}else if( vm.count("discrete") ){
			clearByTime<dm::scada::SDiscreteInfo,dm::scada::CDiscreteMgr>(vm,"离散量","及之前",&dm::scada::CScadaHis::clearDiscreteBefore,&dm::scada::CScadaHis::clearDiscreteBefore);
		}else if( vm.count("measure") ){
			clearByTime<dm::scada::SMeasureInfo,dm::scada::CMeasureMgr>(vm,"测量量","及之前",&dm::scada::CScadaHis::clearMeasureBefore,&dm::scada::CScadaHis::clearMeasureBefore);
		}else if( vm.count("cumulant") ){
			clearByTime<dm::scada::SCumulantInfo,dm::scada::CCumulantMgr>(vm,"累计量","及之前",&dm::scada::CScadaHis::clearCumulantBefore,&dm::scada::CScadaHis::clearCumulantBefore);
		}else if( vm.count("action") ){
			clearByTime<dm::scada::SActionInfo,dm::scada::CActionMgr>(vm,"动作","及之前",&dm::scada::CScadaHis::clearActionBefore,&dm::scada::CScadaHis::clearActionBefore);
		}else{
			cout <<"将清除"<<dt.toString()<<"及之前所有历史数据。确认?(Y/N):";
			cout.flush();
			if( cin.get()=='Y' ){
				cout <<"清除状态量..."<<endl;
				his.clearStatusBefore(ts);

				cout <<"清除离散量..."<<endl;
				his.clearDiscreteBefore(ts);

				cout <<"清除测量量..."<<endl;
				his.clearMeasureBefore(ts);

				cout <<"清除累计量..."<<endl;
				his.clearCumulantBefore(ts);

				cout <<"清除动作..."<<endl;
				his.clearActionBefore(ts);

				cout <<"完成"<<endl;
			}
		}
	}else if( vm["clear"].as<string>()=="andafter" ){
		// 清除含当时及以后的数据
		if( vm.count("status") ){
			clearByTime<dm::scada::SStatusInfo,dm::scada::CStatusMgr>(vm,"状态量","及之后",&dm::scada::CScadaHis::clearStatusAfter,&dm::scada::CScadaHis::clearStatusAfter);
		}else if( vm.count("discrete") ){
			clearByTime<dm::scada::SDiscreteInfo,dm::scada::CDiscreteMgr>(vm,"离散量","及之后",&dm::scada::CScadaHis::clearDiscreteAfter,&dm::scada::CScadaHis::clearDiscreteAfter);
		}else if( vm.count("measure") ){
			clearByTime<dm::scada::SMeasureInfo,dm::scada::CMeasureMgr>(vm,"测量量","及之后",&dm::scada::CScadaHis::clearMeasureAfter,&dm::scada::CScadaHis::clearMeasureAfter);
		}else if( vm.count("cumulant") ){
			clearByTime<dm::scada::SCumulantInfo,dm::scada::CCumulantMgr>(vm,"累计量","及之后",&dm::scada::CScadaHis::clearCumulantAfter,&dm::scada::CScadaHis::clearCumulantAfter);
		}else if( vm.count("action") ){
			clearByTime<dm::scada::SActionInfo,dm::scada::CActionMgr>(vm,"动作","及之后",&dm::scada::CScadaHis::clearActionAfter,&dm::scada::CScadaHis::clearActionAfter);
		}else{
			cout <<"将清除"<<dt.toString()<<"及之后所有历史数据。确认?(Y/N):";
			cout.flush();
			if( cin.get()=='Y' ){
				cout <<"清除状态量..."<<endl;
				his.clearStatusAfter(ts);

				cout <<"清除离散量..."<<endl;
				his.clearDiscreteAfter(ts);

				cout <<"清除测量量..."<<endl;
				his.clearMeasureAfter(ts);

				cout <<"清除累计量..."<<endl;
				his.clearCumulantAfter(ts);

				cout <<"清除动作..."<<endl;
				his.clearActionAfter(ts);

				cout <<"完成"<<endl;
			}
		}
	}
}

struct SPair{
	SPair():first(0),second(0){
	}

	SPair( const int& f,const float& s ):first(f),second(s){
	}

	SPair( const SPair& p ):first(p.first),second(p.second){
	}

	SPair& operator=( const SPair& p ){
		first = p.first;
		second = p.second;
		return *this;
	}

	int first;
	float second;
};
void showCurve( std::vector< SPair >& vs,const int& xLen=200,const int& yLen=50 ){
	int tsBegin,tsEnd;
	float vMax,vMin;

	int size = vs.size();
	if( size>0 ){
		vMax = vs[0].second;
		vMin = vMax;

		for( int i=1;i<size;++i ){
			if( vMax<vs[i].second )
				vMax = vs[i].second;
			if( vMin>vs[i].second )
				vMin = vs[i].second;
		}

		if( vMin==vMax ){
			vMin -= 10;
			vMax += 10;
		}

		tsBegin = vs[0].first;
		tsEnd = vs[size-1].first;

		if( tsBegin==tsEnd ){
			cout <<"起始时标和结束时标一致。"<<endl;
			return;
		}

		float tsCoef = xLen / (tsEnd - tsBegin);
		float vCoef = yLen / (vMax - vMin);

		dm::uint8* pix = new dm::uint8[xLen * yLen];

		for( int i=0;i<xLen;++i )
			for( int j=0;j<yLen;++j )
				pix[i*yLen+j] = 0;

		for( int i=0;i<size;++i ){
			int x = vs[i].first - tsBegin;
			x *= tsCoef;

			int y = yLen-(vs[i].second - vMin)*vCoef;

			pix[x*yLen+y] =  1;
		}

		for( int i=0;i<yLen;++i ){
			pix[i] = 1;
		}

		for( int i=0;i<xLen;++i ){
			pix[i*yLen+yLen/2] = 1;
		}

		for( int i=0;i<yLen;++i ){
			for( int j=0;j<xLen;++j ){
				if( pix[j*yLen+i] )
					cout <<".";
				else
					cout <<' ';
			}
			cout <<endl;
		}

		delete[] pix;
	}else{
		cout <<"没有数据"<<endl;
	}
}

void cmd_data( const variables_map& vm ){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();

	dm::scada::id_t id;
	dm::CDateTime s;
	dm::CDateTime e;

	if( vm.count("id") )
		id = vm["id"].as<int>();

	if( vm.count("after") ){
		if( !s.fromString(vm["after"].as<string>().c_str() ) ){
			cout <<"--after 时标不正确"<<endl;
			return;
		}
	}

	if( vm.count("before") ){
		if( !e.fromString(vm["before"].as<string>().c_str() ) ){
			cout <<"--before 时标不正确"<<endl;
			return;
		}
	}

	if( vm.count("status") ){
		dm::scada::CScadaHis::status_his_t d;
		if( vm.count("id") ){
			int idx = dm::scada::CStatusMgr::ins().indexById(id);
			if( idx<0 ){
				cout <<"错误：不能找到状态量(id:"<<id<<")"<<endl;
				return;
			}

			if( s.isValid() ){
				if( e.isValid() )
					his.getStatusBetween(dm::scada::CStatusMgr::ins().info(idx)->name,s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getStatusAfter(dm::scada::CStatusMgr::ins().info(idx)->name,s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getStatusBefore(dm::scada::CStatusMgr::ins().info(idx)->name,e.toTimeStamp(),d);
				else
					his.getStatus(dm::scada::CStatusMgr::ins().info(idx)->name,d);
			}
		}else if( vm.count("name")){
			if( s.isValid() ){
				if( e.isValid() )
					his.getStatusBetween(vm["name"].as<string>().c_str(),s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getStatusAfter(vm["name"].as<string>().c_str(),s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getStatusBefore(vm["name"].as<string>().c_str(),e.toTimeStamp(),d);
				else
					his.getStatus(vm["name"].as<string>().c_str(),d);
			}
		}else{
			if( s.isValid() ){
				if( e.isValid() )
					his.getStatusBetween(s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getStatusAfter(s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getStatusBefore(e.toTimeStamp(),d);
				else
					his.getStatus(d);
			}
		}

		cout <<"获取状态量记录 "<<d.count()<<"条"<<endl;
		cout <<"序号, 名字, 设备, 描述, 值, 值描述, 数据时刻, 记录时刻, 记录原因"<<endl;
		for( int i=0;i<d.count();++i ){
			int idx = dm::scada::CStatusMgr::ins().indexByName(d[i].name.c_str());
			cout <<i+1<<','
					<<d[i].name.c_str()<<',';

			if( idx==-1 ){
				cout <<"未知设备"<<','
						<<"未知信号"<<',';
			}else{
				cout <<dm::scada::CStatusMgr::ins().deviceDesc(idx) <<','
						<<dm::scada::CStatusMgr::ins().desc(idx) <<',';
			}
			cout <<int(d[i].v)<<',';
			if( idx==-1 )
				cout <<"未定义"<<',';
			else
				cout <<dm::scada::CStatusMgr::ins().valueDesc(idx,d[i].v)<<',';

			cout <<dm::CDateTime(d[i].ts).toString()<<','
					<<dm::CDateTime(d[i].op).toString()<<','
					<<int(d[i].cause)
					<<endl;
		}
	}else if( vm.count("discrete")){
		dm::scada::CScadaHis::discrete_his_t d;
		if( vm.count("id") ){
			int idx = dm::scada::CDiscreteMgr::ins().indexById(id);
			if( idx<0 ){
				cout <<"错误：不能找到离散量(id:"<<id<<")"<<endl;
				return;
			}

			if( s.isValid() ){
				if( e.isValid() )
					his.getDiscreteBetween(dm::scada::CDiscreteMgr::ins().info(idx)->name,s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getDiscreteAfter(dm::scada::CDiscreteMgr::ins().info(idx)->name,s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getDiscreteBefore(dm::scada::CDiscreteMgr::ins().info(idx)->name,e.toTimeStamp(),d);
				else
					his.getDiscrete(dm::scada::CDiscreteMgr::ins().info(idx)->name,d);
			}
		}else if(vm.count("name")){
			if( s.isValid() ){
				if( e.isValid() )
					his.getDiscreteBetween(vm["name"].as<string>().c_str(),s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getDiscreteAfter(vm["name"].as<string>().c_str(),s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getDiscreteBefore(vm["name"].as<string>().c_str(),e.toTimeStamp(),d);
				else
					his.getDiscrete(vm["name"].as<string>().c_str(),d);
			}
		}else{
			if( s.isValid() ){
				if( e.isValid() )
					his.getDiscreteBetween(s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getDiscreteAfter(s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getDiscreteBefore(e.toTimeStamp(),d);
				else
					his.getDiscrete(d);
			}
		}

		cout <<"获取离散量记录 "<<d.count()<<"条"<<endl;
		cout <<"序号,名字,值,数据时刻,记录时刻,记录原因"<<endl;
		for( int i=0;i<d.count();++i ){
			cout <<i+1<<','
					<<d[i].name.c_str()<<','
					<<int(d[i].v)<<','
					<<dm::CDateTime(d[i].ts).toString()<<','
					<<dm::CDateTime(d[i].op).toString()<<','
					<<int(d[i].cause)
					<<endl;
		}
	}else if( vm.count("measure") ){
		dm::scada::CScadaHis::measure_his_t d;
		if( vm.count("id") ){
			int idx = dm::scada::CMeasureMgr::ins().indexById(id);
			if( idx<0 ){
				cout <<"错误：不能找到测量量(id:"<<id<<")"<<endl;
				return;
			}

			if( s.isValid() ){
				if( e.isValid() )
					his.getMeasureBetween(dm::scada::CMeasureMgr::ins().info(idx)->name,s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getMeasureAfter(dm::scada::CMeasureMgr::ins().info(idx)->name,s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getMeasureBefore(dm::scada::CMeasureMgr::ins().info(idx)->name,e.toTimeStamp(),d);
				else
					his.getMeasure(dm::scada::CMeasureMgr::ins().info(idx)->name,d);
			}
		}else if( vm.count("name")){
			if( s.isValid() ){
				if( e.isValid() )
					his.getMeasureBetween(vm["name"].as<string>().c_str(),s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getMeasureAfter(vm["name"].as<string>().c_str(),s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getMeasureBefore(vm["name"].as<string>().c_str(),e.toTimeStamp(),d);
				else
					his.getMeasure(vm["name"].as<string>().c_str(),d);
			}
		}else{
			if( s.isValid() ){
				if( e.isValid() )
					his.getMeasureBetween(s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getMeasureAfter(s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getMeasureBefore(e.toTimeStamp(),d);
				else
					his.getMeasure(d);
			}
		}

		cout <<"获取测量量记录 "<<d.count()<<"条"<<endl;
		cout <<"序号,名字,值,数据时刻,记录时刻,记录原因"<<endl;
		for( int i=0;i<d.count();++i ){
			cout <<i+1<<','
					<<d[i].name.c_str()<<','
					<<d[i].v<<','
					<<dm::CDateTime(d[i].ts).toString()<<','
					<<dm::CDateTime(d[i].op).toString()<<','
					<<int(d[i].cause)
					<<endl;
		}
	}else if( vm.count("cumulant") ){
		dm::scada::CScadaHis::cumulant_his_t d;
		if( vm.count("id") ){
			int idx = dm::scada::CCumulantMgr::ins().indexById(id);
			if( idx<0 ){
				cout <<"错误：不能找到累计量(id:"<<id<<")"<<endl;
				return;
			}

			if( s.isValid() ){
				if( e.isValid() )
					his.getCumulantBetween(dm::scada::CCumulantMgr::ins().info(idx)->name,s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getCumulantAfter(dm::scada::CCumulantMgr::ins().info(idx)->name,s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getCumulantBefore(dm::scada::CCumulantMgr::ins().info(idx)->name,e.toTimeStamp(),d);
				else
					his.getCumulant(dm::scada::CCumulantMgr::ins().info(idx)->name,d);
			}
		}else if( vm.count("name")){
			if( s.isValid() ){
				if( e.isValid() )
					his.getCumulantBetween(vm["name"].as<string>().c_str(),s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getCumulantAfter(vm["name"].as<string>().c_str(),s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getCumulantBefore(vm["name"].as<string>().c_str(),e.toTimeStamp(),d);
				else
					his.getCumulant(vm["name"].as<string>().c_str(),d);
			}
		}else{
			if( s.isValid() ){
				if( e.isValid() )
					his.getCumulantBetween(s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getCumulantAfter(s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getCumulantBefore(e.toTimeStamp(),d);
				else
					his.getCumulant(d);
			}
		}

		cout <<"获取累计量记录 "<<d.count()<<"条"<<endl;
		cout <<"序号,名字,值,数据时刻,记录时刻,记录原因"<<endl;
		for( int i=0;i<d.count();++i ){
			cout <<i+1<<','
					<<d[i].name.c_str()<<','
					<<d[i].v<<','
					<<dm::CDateTime(d[i].ts).toString()<<','
					<<dm::CDateTime(d[i].op).toString()<<','
					<<int(d[i].cause)
					<<endl;
		}
	}else if( vm.count("action") ){
		dm::scada::CScadaHis::action_his_t d;
		if( vm.count("id") ){
			int idx = dm::scada::CActionMgr::ins().indexById(id);
			if( idx<0 ){
				cout <<"错误：不能找到动作(id:"<<id<<")"<<endl;
				return;
			}

			if( s.isValid() ){
				if( e.isValid() )
					his.getActionBetween(dm::scada::CActionMgr::ins().info(idx)->name,s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getActionAfter(dm::scada::CActionMgr::ins().info(idx)->name,s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getActionBefore(dm::scada::CActionMgr::ins().info(idx)->name,e.toTimeStamp(),d);
				else
					his.getAction(dm::scada::CActionMgr::ins().info(idx)->name,d);
			}
		}else if( vm.count("name")){
			if( s.isValid() ){
				if( e.isValid() )
					his.getActionBetween(vm["name"].as<string>().c_str(),s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getActionAfter(vm["name"].as<string>().c_str(),s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getActionBefore(vm["name"].as<string>().c_str(),e.toTimeStamp(),d);
				else
					his.getAction(vm["name"].as<string>().c_str(),d);
			}
		}else{
			if( s.isValid() ){
				if( e.isValid() )
					his.getActionBetween(s.toTimeStamp(),e.toTimeStamp(),d);
				else
					his.getActionAfter(s.toTimeStamp(),d);
			}else{
				if( e.isValid() )
					his.getActionBefore(e.toTimeStamp(),d);
				else
					his.getAction(d);
			}
		}

		cout <<"获取动作记录 "<<d.count()<<"条"<<endl;
		cout <<"序号,名字,值,数据时刻,记录时刻,记录原因"<<endl;
		for( int i=0;i<d.count();++i ){
			cout <<i+1<<','
					<<d[i].name.c_str()<<','
					<<int(d[i].v)<<','
					<<dm::CDateTime(d[i].ts).toString()<<','
					<<dm::CDateTime(d[i].op).toString()<<','
					<<int(d[i].cause)
					<<endl;
		}
	}else{
		cout <<"必须指定数据类型"<<endl;
	}
}

void cmd_curve( const variables_map& vm ){
	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();
	dm::CTimeStamp ts;

	dm::CDateTime dt;

	if( !vm.count("timestamp") ){
		cout <<"请使用--timestamp指定时刻"<<endl;
		return;
	}

	if( !dt.fromString(vm["timestamp"].as<string>().c_str()) ){
		cout <<"--timestamp时标格式不正确"<<vm["timestamp"].as<string>()<<endl;
		return;
	}

	dt.toTimeStamp(ts);

	if( !vm.count("secs") ){
		cout <<"请使用--secs指定时长"<<endl;
		return;
	}

	int secs = vm["secs"].as<int>();

	int xLen = 200;
	int yLen = 50;

	if( vm.count("x-len"))
		xLen = vm["x-len"].as<int>();

	if( vm.count("y-len"))
		yLen = vm["y-len"].as<int>();

	if( vm.count("measure") ){
		const dm::scada::SMeasureInfo* info = getInfo<dm::scada::SMeasureInfo,dm::scada::CMeasureMgr>(vm,"测量量");
		if( info ){
			std::vector<SPair > vs;
			dm::scada::SHisRcdMeasure rcd;
			rcd.name = info->name;
			for( int i=0;i<secs;++i ){
				rcd.ts = ts;
				his.measureAt(rcd);
				vs.push_back( SPair(ts.seconds(),rcd.v));
				ts.addSec(1);
			}
			showCurve(vs,xLen,yLen);
		}
	}else if( vm.count("cumulant") ){
		const dm::scada::SCumulantInfo* info = getInfo<dm::scada::SCumulantInfo,dm::scada::CCumulantMgr>(vm,"累计量");
		if( info ){
			std::vector<SPair > vs;
			dm::scada::SHisRcdCumulant rcd;
			rcd.name = info->name;
			for( int i=0;i<secs;++i ){
				rcd.ts = ts;
				his.cumulantAt(rcd);
				vs.push_back( SPair(ts.seconds(),rcd.v));
				ts.addSec(1);
			}

			showCurve(vs,xLen,yLen);
		}
	}else{
		cout <<"曲线显示必须制定测量量或累计量"<<endl;
	}
}

void cmd_test( const variables_map& vm ){
	bool done = false;

	dm::scada::CScadaHis& his = dm::scada::CScadaHis::ins();

	if( vm.count("all")||vm.count("status") ){
		done = true;
		dm::scada::SHisRcdStatus rcd;

		if( !vm.count("id") ){
			cout <<"错误：请使用参数id指定状态量id号"<<endl;
			return;
		}

		int idx = dm::scada::CStatusMgr::ins().indexById(vm["id"].as<int>());
		if( idx<0 ){
			cout <<"错误：不存在状态量(id:"<<vm["id"].as<int>()<<")"<<endl;
			return;
		}

		rcd.name = dm::scada::CStatusMgr::ins().info(idx)->name;

		if( !vm.count("value") ){
			cout <<"错误：请使用参数value指定状态量的值。可以取值0，1，2，3"<<endl;
			return;
		}

		rcd.v = atoi(vm["value"].as<string>().c_str());

		if( !vm.count("timestamp") )
			rcd.ts = dm::CTimeStamp::cur();
		else{
			if( !dm::scada::CScadaHis::string2timeStmp(vm["timestamp"].as<string>().c_str(),rcd.ts) ){
				cout <<"错误：参数timestamp指定的时标格式错误"<<endl;
				return;
			}
		}
		rcd.op = dm::CTimeStamp::cur();
		rcd.cause = rcd.Manual;
		his.appendStatus(rcd);
	}

	if( vm.count("all")||vm.count("discrete") ){
		done = true;
		dm::scada::SHisRcdDiscrete rcd;

		if( !vm.count("id") ){
			cout <<"错误：请使用参数id指定离散量id号"<<endl;
			return;
		}

		int idx = dm::scada::CDiscreteMgr::ins().indexById(vm["id"].as<int>());
		if( idx<0 ){
			cout <<"错误：不存在离散量(id:"<<vm["id"].as<int>()<<")"<<endl;
			return;
		}

		rcd.name = dm::scada::CDiscreteMgr::ins().info(idx)->name;

		if( !vm.count("value") ){
			cout <<"错误：请使用参数value指定离散量的值"<<endl;
			return;
		}

		rcd.v = atoi(vm["value"].as<string>().c_str());

		if( !vm.count("timestamp") )
			rcd.ts = dm::CTimeStamp::cur();
		else{
			if( !dm::scada::CScadaHis::string2timeStmp(vm["timestamp"].as<string>().c_str(),rcd.ts) ){
				cout <<"错误：参数timestamp指定的时标格式错误"<<endl;
				return;
			}
		}
		rcd.op = dm::CTimeStamp::cur();
		rcd.cause = rcd.Manual;
		his.appendDiscrete(rcd);
	}

	if( vm.count("all")||vm.count("measure") ){
		done = true;
		dm::scada::SHisRcdMeasure rcd;

		if( !vm.count("id") ){
			cout <<"错误：请使用参数id指定id号"<<endl;
			return;
		}

		int idx = dm::scada::CMeasureMgr::ins().indexById(vm["id"].as<int>());
		if( idx<0 ){
			cout <<"错误：不存在测量量(id:"<<vm["id"].as<int>()<<")"<<endl;
			return;
		}

		rcd.name = dm::scada::CMeasureMgr::ins().info(idx)->name;

		if( !vm.count("value") ){
			cout <<"错误：请使用参数value指定值"<<endl;
			return;
		}

		rcd.v = atof(vm["value"].as<string>().c_str());

		if( !vm.count("timestamp") )
			rcd.ts = dm::CTimeStamp::cur();
		else{
			if( !dm::scada::CScadaHis::string2timeStmp(vm["timestamp"].as<string>().c_str(),rcd.ts) ){
				cout <<"错误：参数timestamp指定的时标格式错误"<<endl;
				return;
			}
		}
		rcd.op = dm::CTimeStamp::cur();
		rcd.cause = rcd.Manual;
		his.appendMeasure(rcd);
	}

	if( vm.count("all")||vm.count("cumulant") ){
		done = true;
		dm::scada::SHisRcdCumulant rcd;

		if( !vm.count("id") ){
			cout <<"错误：请使用参数id指定id号"<<endl;
			return;
		}

		int idx = dm::scada::CCumulantMgr::ins().indexById(vm["id"].as<int>());
		if( idx<0 ){
			cout <<"错误：不存在累计量(id:"<<vm["id"].as<int>()<<")"<<endl;
			return;
		}

		rcd.name = dm::scada::CCumulantMgr::ins().info(idx)->name;

		if( !vm.count("value") ){
			cout <<"错误：请使用参数value指定值"<<endl;
			return;
		}

		rcd.v = atol(vm["value"].as<string>().c_str());

		if( !vm.count("timestamp") )
			rcd.ts = dm::CTimeStamp::cur();
		else{
			if( !dm::scada::CScadaHis::string2timeStmp(vm["timestamp"].as<string>().c_str(),rcd.ts) ){
				cout <<"错误：参数timestamp指定的时标格式错误"<<endl;
				return;
			}
		}
		rcd.op = dm::CTimeStamp::cur();
		rcd.cause = rcd.Manual;
		his.appendCumulant(rcd);
	}

	if( !done )
		cout <<"test参数必须指定需要插入的数据类型。请使用参数--status,--discrete,--measure,--cumulant,或者--all指定所有类型"<<endl;
}

void cmd_init( const variables_map& ){
		cout <<"更新数据库...";
		dm::scada::CScadaHis::ins();
		cout <<"成功"<<endl;
}
